package nl.scalasim.actors.traits

import nl.scalasim._
import nl.scalasim.util.Storage
import nl.scalasim.controlactors.Guildmaster

/**
 * StorageActors provide storage for goods.
 *
 * <table>
 * <tr><th>Incoming</th><th>Outgoing</th></tr>
 * <tr><td>Store(goods, amount)</td><td>Stored(goods, amount)</td></tr>
 * <tr><td>Claim(goods, amount)</td><td>Claimed(goods, amount)</td></tr>
 * <tr><td>Retrieve(goods, amount)</td><td>Retrieved(goods, amount)</td></tr>
 * <tr><td>GetStorageState</td><td>StorageState(stored, capacity)</td></tr>
 * </table>
 *
 *
 * @author Yigal Duppen
 * @since Oct 28, 2010
 */
trait StorageActor extends SimulationActor {

  /**
   * Defines the maximal capacity for each type of goods
   */
  val capacity: Map[Goods, Int]

  /**
   * Defines the total capacity for this intermediate storage. 
   */
  val totalCapacity: Int

  /**
   * The actual storage
   */
  private val storage = new Storage(capacity, totalCapacity)

  private[traits] override def stored = storage.view
  private[traits] override def maxStorageCapacity = totalCapacity

  def advertise(g: Guildmaster) = {
    g ! Advertise(this, storage.view)
  }

  def handleStore: PartialFunction[Any, Unit] = {
    case Store(goods, amount) => {
      reply(Stored(goods, storage.store(goods, amount)))
    }
  }
  callbacks :+= handleStore

  
  def handleRetrieve: PartialFunction[Any, Unit] = {
    case Retrieve(goods, amount) => {
      reply(Retrieved(goods, storage.retrieve(goods, amount)))
    }
  }
  callbacks :+= handleRetrieve

}